package com.seamtop.cuber.server.service.impl;

import com.seamtop.cuber.common.base.DataObject;
import com.seamtop.cuber.common.entriy.*;
import com.seamtop.cuber.server.base.BaseBuilder;
import com.seamtop.cuber.server.job.JobKits;
import com.seamtop.cuber.server.job.ReducerJobFactory;
import com.seamtop.cuber.server.service.CuberJobService;
import com.seamtop.cuber.server.service.JobRecordService;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;

/**
 * Created by zongjunfeng on 2015/8/20.
 */
@Service("cuberJobService")
public class CuberJobServiceImpl implements CuberJobService {

    private static final Logger LOG = LoggerFactory.getLogger(CuberJobServiceImpl.class);

    @Autowired
    private Scheduler scheduler ;

    @Autowired
    private JobRecordService jobRecordService;


    @Override
    public void loadReducerJob() throws Exception {
        LOG.info("Load Cuber Reducer Job Start!");
        HashMap<String, CuberReducer> reducerHashMap = DataObject.getCuberReducerMap();
        for (String reducerId : reducerHashMap.keySet()) {
            CuberReducer reducer = reducerHashMap.get(reducerId);
            if(reducer.getStatus() != 0){
                continue;
            }
            String cronExpression = JobKits.getCrontabExpress(reducer);
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(reducerId, "reducer").withSchedule(scheduleBuilder).build();
            JobDetail jobDetail = JobBuilder.newJob(ReducerJobFactory.class).withIdentity(reducerId, "reducer").build();
            jobDetail.getJobDataMap().put("reducer", reducer);
            scheduler.scheduleJob(jobDetail, trigger);
            LOG.info("Load Reducer Job [reducerId:"+reducer.getReducerId()+" cron:"+cronExpression+"] success!");
        }
        LOG.info("Load Cuber Reducer Job End!");
    }

    @Override
    public void reLoadReducerJob() throws Exception{
        LOG.info("Load Cuber Reducer Job Start!");
        HashMap<String, CuberReducer> reducerHashMap = DataObject.getCuberReducerMap();
        for (String reducerId : reducerHashMap.keySet()) {
            CuberReducer reducer = reducerHashMap.get(reducerId);
            String cronExpression = JobKits.getCrontabExpress(reducer);
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(reducerId, "reducer").withSchedule(scheduleBuilder).build();
            JobDetail jobDetail = JobBuilder.newJob(ReducerJobFactory.class).withIdentity(reducerId, "reducer").build();
            jobDetail.getJobDataMap().put("reducer", reducer);
            scheduler.scheduleJob(jobDetail, trigger);
            LOG.info("Load Reducer Job [reducerId:"+reducer.getReducerId()+" cron:"+cronExpression+"] success!");
        }
        LOG.info("Load Cuber Reducer Job End!");
    }



    @Override
    public void loadCounterJob() throws Exception {
        LOG.info("Load Cuber Counter Job Start!");
        HashMap<String, CuberCounter> cuberCounterMap = DataObject.getCuberCounterMap();
        for (String counterName : cuberCounterMap.keySet()) {
            CuberCounter cuberCounter = cuberCounterMap.get(counterName);
            CuberCounterSet cuberCounterSet = DataObject.getCuberCounterSetMap().get(cuberCounter.getCounterSetId());
            //查看是否启用定时统计
            if(cuberCounterSet.getCounterSettings().isTimeSettingEnable()){
                CuberReducer reducer = JobKits.getCronReducerOfCounter(cuberCounter);
                String cronExpression = JobKits.getCrontabExpress(reducer);
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
                CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(reducer.getReducerId(), "reducer").withSchedule(scheduleBuilder).build();
                JobDetail jobDetail = JobBuilder.newJob(ReducerJobFactory.class).withIdentity(reducer.getReducerId(), "reducer").build();
                jobDetail.getJobDataMap().put("reducer", reducer);
                scheduler.scheduleJob(jobDetail, trigger);
                LOG.info("Load Counter Job [reducerId:"+cuberCounter.getCounterId()+" cron:"+cronExpression+"] success!");
            }

        }
        LOG.info("Load Cuber Counter Job End!");
    }


    public void reLoadCounterJob() throws Exception{
        LOG.info("Load Cuber Counter Job Start!");
        HashMap<String, CuberCounter> cuberCounterMap = DataObject.getCuberCounterMap();
        for (String counterName : cuberCounterMap.keySet()) {
            CuberCounter cuberCounter = cuberCounterMap.get(counterName);
            //查看是否启用定时统计
            CuberCounterSet cuberCounterSet = DataObject.getCuberCounterSetMap().get(cuberCounter.getCounterSetId());
            if(cuberCounterSet.getCounterSettings().isTimeSettingEnable()){
                CuberReducer reducer = JobKits.getCronReducerOfCounter(cuberCounter);
                String cronExpression = JobKits.getCrontabExpress(reducer);
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
                CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(reducer.getReducerId(), "reducer").withSchedule(scheduleBuilder).build();
                JobDetail jobDetail = JobBuilder.newJob(ReducerJobFactory.class).withIdentity(reducer.getReducerId(), "reducer").build();
                jobDetail.getJobDataMap().put("reducer", reducer);
                scheduler.scheduleJob(jobDetail, trigger);
                LOG.info("Load Counter Job [reducerId:"+cuberCounter.getCounterId()+" cron:"+cronExpression+"] success!");
            }

        }
        LOG.info("Load Cuber Reducer Job End!");
    }

    @Override
    public void execute(CuberReducerJob cuberReducerJob){
        //增加job执行记录
        JobRecord jobRecord = new JobRecord();
        jobRecord.setReducerId(cuberReducerJob.getReducer().getReducerId());
        jobRecord.setExecuteStartTime(new Date());
        jobRecordService.addJobRecord(jobRecord);
        int t = jobRecord.getId();
        boolean result = false;
        try{
            BaseBuilder.getBaseHandler().execute(cuberReducerJob);
            result = true;
        }catch (Exception e){
            e.printStackTrace();
        }
        jobRecord.setId(t);
        jobRecord.setExecuteEndTime(new Date());
        if(result){
            jobRecord.setExecuteDesc("success");
            jobRecord.setResult(1);
        }else{
            jobRecord.setExecuteDesc("failure");
            jobRecord.setResult(2);
        }
        jobRecordService.updateJobRecord(jobRecord);
    }


}
